/**
 * 物攻技能计算
 * @param {*} fight_data 
 * @param {*} src_unit 
 * @param {*} skill_name 
 * @param {*} skill_level 
 */
export function computing_ad_skill(fight_data, src_unit, skill_name, skill_level) {
	console.debug(`物攻技能计算 ${skill_name} ${skill_level}`);

	// 技能配置
	let skill_data = G.SkillData.default[skill_name];

	// 物攻前触发
	if (skill_data && skill_data["物攻前触发"]) {
		console.debug(`物攻前触发 ${skill_name} `)
		skill_data["物攻前触发"](fight_data, src_unit, skill_name);
	}

	let target_number = src_unit["指令"]["目标"];
	let target_unit = G.FightUtils.get_fight_unit_by_number(fight_data, target_number);

	// 如果目标已经不可操作则更换目标
	if (target_unit === undefined) {
		target_unit = G.FightUtils.get_enemy_team_single_survive_unit(fight_data, src_unit);
		console.debug(`物攻技能计算 ===> 目标单位不存在 重新寻找目标单位：${target_unit !== undefined}`);
	} else if (!G.FightUnitUtils.get_target_unit_status(src_unit, target_unit, 1)) {
		target_unit = G.FightUtils.get_enemy_team_single_survive_unit(fight_data, src_unit);
		console.debug(`物攻技能计算 ===> 目标单位无法选中 重新寻找目标单位：${target_unit !== undefined}`);
	}
	if (target_unit === undefined) {
		console.debug(`物攻技能计算 ===> 仍然找不到目标单位，跳过`);
		return false;
	}
	let target_count = 1;

	if (skill_data["目标"]) {
		target_count = skill_data["目标"](fight_data, src_unit, target_unit, skill_level);
	} else {
		console.debug(`物理技能 ${skill_name} 未定义目标计算`);
	}

	// 技能如果技能攻击目标是多个 则获取到的是多个敌人
	let target_unit_list = G.FightUtils.get_enemy_team_group_survive_unit(fight_data, src_unit, target_unit, target_count);

	// 分身术破解后无法攻击
	for (let index = 0; index < target_unit_list.length; index++) {
		let target = target_unit_list[index];
		if (target["法术状态"] && target["法术状态"]["分身术"] && target["法术状态"]["分身术"]["破解"] === undefined) {
			target["法术状态"]["分身术"]["破解"] = 1;
			target_unit_list.splice(index, 1);
			console.debug(`物攻技能计算 ===> 分身术破解无法攻击，跳过`);
			return;
		}
	}

	target_count = target_unit_list.length;

	if (target_count === 0) {
		console.debug(`物攻技能计算 ===> 没有目标单位，跳过`);
		return false;
	}

	// 获取技能消耗数据
	let consummer_value = 0;
	let consummer_type = "";
	if (skill_data && skill_data["消耗"]) {
		let res = skill_data["消耗"](fight_data, src_unit, target_count);
		if (res) {
			consummer_value = res[0];
			consummer_type = res[1];
		}
	}
	// 如果需要的消耗类型不够则行动失败
	if (!G.FightUnitUtils.excute_unit_skill_consummer(fight_data, src_unit, consummer_type, consummer_value, skill_name)) {
		fight_data["战斗流程"].push({ "流程": 6, "战斗提示": { "内容": "行动失败", "编号": src_unit["编号"] } });
		return;
	}

	// 基础计算 计算技能的连击数据
	console.debug(`物理技能基础计算 : ${src_unit["编号"]} 目标数: ${target_unit_list.length}`)
	let commone_data = { "返回": false, "重复次数": 1, "起始伤害": 1, "叠加伤害": 0, "重复提示": false, "连击次数": 1 };
	if (skill_data && skill_data["基础物理计算"]) {
		commone_data = skill_data["基础物理计算"](fight_data, src_unit, target_unit_list, skill_level);
	}
	console.debug(`物理技能基础计算结果 ===> ${JSON.stringify(data)}`)

	// 超级连击多攻击一次
	if (src_unit["超级连击"] === true && G.RandomUtils.chance(20)) {
		commone_data["连击次数"] += 1;
	}

	// 出其不意
	if (src_unit["认证码"] && src_unit["特殊状态"]["出其不意"] &&
		!fight_data["特殊状态"]["出其不意"][src_unit["队伍"]]["技能"].has(skill_name)) {
		commone_data["起始伤害"] = commone_data["起始伤害"] * 1.15;
	}

	// 实际的攻击次数
	let attack_count = 0;
	// 攻击每个目标
	for (let index = 0; index < target_unit_list.length; index++) {
		// 重复攻击 commone_result["重复次数"] 次
		for (let cf_index = 0; cf_index < commone_data["重复次数"]; cf_index++) {
			let target_unit = target_unit_list[index];
			//连续攻击目标 commone_result["连击次数"] 次 
			for (let lj_index = 0; lj_index < commone_data["连击次数"]; lj_index++) {
				attack_count++;
				//本次攻击流程演算
				computing_ad_skill_process(fight_data, src_unit, target_unit, skill_name, lj_index + 1, commone_data);
				//提示内容
				let text = "";
				// 指定技能添加提示内容
				if (skill_data["提示"]) {
					text = `${src_unit["名称"]}使用了${skill_name}`;
				}
				// 特定技能物理连击触发算法
				if (skill_data["物理连击触发"]) {
					skill_data["物理连击触发"](fight_data, src_unit, target_unit, target_unit_list, lj_index + 1);
				}
				// 流程提示信息
				fight_data["战斗流程"][fight_data["战斗流程"].length - 1]["提示"] = { "类型": "法术", "名称": text, "允许": true };
				fight_data["战斗流程"][fight_data["战斗流程"].length - 1]["技能提示"] = { "内容": `【物理】${skill_name}`, "编号": src_unit["编号"] };
				// 非第一次攻击 并且不允许重复 则关闭当前流程的提示
				if (lj_index > 0 && !commone_data["重复提示"]) {
					fight_data["战斗流程"][fight_data["战斗流程"].length - 1]["提示"]["允许"] = false;
				}
				// 连击完成 并且已经攻击完所有目标 返回原位置
				if (lj_index === commone_data["连击次数"] - 1 && index === target_unit_list.length - 1) {
					fight_data["战斗流程"][fight_data["战斗流程"].length - 1]["返回"] = true;
				} else if (!G.FightUnitUtils.get_unit_process_status(fight_data, src_unit)) {
					//攻击方无法继续行动 返回原位置
					fight_data["战斗流程"][fight_data["战斗流程"].length - 1]["返回"] = true;
					break;
				} else if (!G.FightUnitUtils.get_target_unit_status(src_unit, target_unit, 1)) {
					//目标死亡 返回原位置
					fight_data["战斗流程"][fight_data["战斗流程"].length - 1]["返回"] = true;
					break;
				}
			}
		}
	}
	G.FightUtils.add_waiting_play_time(fight_data, target_unit_list.length * 2 , "物理技能");
	G.FightUtils.add_waiting_play_time(fight_data, 1 * attack_count, "物理技能");

	// 技能结尾附加计算
	if (skill_data["结尾附加"]) {
		console.debug(`物理技能结尾附加 : ${src_unit["编号"]} ${skill_name} ${target_unit_list.length}`);
		skill_data["结尾附加"](fight_data, src_unit, target_unit_list, skill_name, skill_level, attack_count);
	}
	if (src_unit["法术状态"]["狂袭"] && src_unit["法术状态"]["狂袭"]["死亡"]) {
		G.FightComputingUtils.remove_hp_js_and_play(fight_data, src_unit, target_unit_list[0], src_unit["气血"]);
	}

	// 物理攻击后法术状态算法
	for (const key in src_unit["法术状态"]) {
		if (G.SkillData.default[key] && G.SkillData.default[key]["物攻后触发"]) {
			console.debug(`物攻后触发 => 法术状态 ${key}`);
			G.SkillData.default[key]["物攻后触发"](fight_data, src_unit, target_unit_list, skill_name, skill_level);
		}
	}

	// 物理攻击后特殊状态算法
	for (const key in src_unit["特殊状态"]) {
		if (G.SkillData.default[key] && G.SkillData.default[key]["物攻后触发"]) {
			console.debug(`物攻后触发 => 特殊状态 ${key}`);
			G.SkillData.default[key]["物攻后触发"](fight_data, src_unit, target_unit_list, skill_name, skill_level);
		}
	}

	// 物理攻击后内丹算法触发
	for (const key in src_unit["内丹属性"]) {
		let nei_dan_data = G.NeiDanData.default[key]
		if (nei_dan_data && nei_dan_data["物攻后触发"]) {
			console.debug(`物攻后触发 => 内丹属性 ${key}`);
			nei_dan_data["物攻后触发"](fight_data, src_unit, target_unit_list, skill_name, skill_level);
		}
	}

}

/**
 * 物攻技能流程计算 
 * @param {*} fight_data 
 * @param {*} src_unit 
 * @param {*} target_unit 
 * @param {*} skill_name 技能名称
 * @param {*} attack_number 第几次攻击
 */
export function computing_ad_skill_process(fight_data, src_unit, target_unit, skill_name, attack_number, commone_data) {

	console.debug(`物攻技能流程计算 => : ${src_unit["编号"]} ${target_unit["编号"]}`)
	fight_data["战斗流程"].push({
		"流程": 1,
		"攻击方": src_unit["编号"],
		"被攻击": [{ "编号": target_unit["编号"], "特效": [] }]
	});

	let current_process_data_index = fight_data["战斗流程"].length - 1;


	if (ex_skill[skill_name]) {
		fight_data["战斗流程"][current_process_data_index]["特技名称"] = skill_name;
	}

	// 基础物理伤害
	let damage = G.FightPhysicalAttack.get_ad_damage(fight_data, src_unit, target_unit, skill_name);

	// 基础物理伤害乘以叠加伤害
	damage = damage * (commone_data["起始伤害"] + commone_data["叠加伤害"] * attack_number);

	// 默认额外伤害
	let default_damage = { "伤害": damage, "必杀几率": 0, "暴击倍率": 2, "浮空概率": 0 };

	// 额外物理伤害
	let skill_data = G.SkillData.default[skill_name];
	if (skill_data && skill_data["额外物理伤害"]) {
		let res = skill_data["额外物理伤害"](fight_data, src_unit, target_unit, damage, attack_number);
		if (res) {
			default_damage = res;
		}
	}

	// 浮空概率及九黎浮空处理
	if (default_damage["浮空概率"] > 0 && src_unit["法术状态"]["怒哮"]) {
		default_damage["浮空概率"] += 30;
	}
	if (G.FightUnitUtils.check_fight_unit_jingmai(src_unit, "九黎城", "识破") && G.FightUtils.get_wx_suppress(src_unit["攻击五行"], target_unit["防御五行"])) {
		default_damage["浮空概率"] += 10;
	}

	// TODO 应当提取出来
	if (target_unit["九黎浮空"]) {
		if (G.RandomUtils.chance(default_damage["浮空概率"])) {
			src_unit["浮空人数"] = (src_unit["浮空人数"] || 0) + 1;
			target_unit["九黎浮空"] = src_unit["编号"];
			fight_data["战斗流程"][current_process_data_index]["浮空目标"] = target_unit["编号"]

			G.FightStatusUtils.canel_unit_status(fight_data, "怒哮", src_unit);

			if (src_unit["飞扬生效"] && src_unit["浮空人数"] === 5 && (src_unit["飞扬次数"] || 0) < 3) {
				src_unit["飞扬增伤"] = (src_unit["飞扬增伤"] || 1) + 0.06;
				src_unit["飞扬次数"] = (src_unit["飞扬次数"] || 0) + 1;
			}
			if (G.FightUnitUtils.check_unit_shen_qi_skill(src_unit, "鸣空")) {
				if (src_unit["神器加成"] < 6) {
					src_unit["神器加成"] += 1;
				}
				default_damage["必杀几率"] += src_unit["神器"]["等级"] * 12;
			}
			if (skill_name === "一斧开天") {
				fight_data["战斗流程"][current_process_data_index]["致使浮空"] = true;
			}
		} else {
			if (skill_name === "一斧开天") {
				fight_data["战斗流程"][current_process_data_index]["未浮空"] = true;
				let gl = 26;
				if (G.FightUnitUtils.check_fight_unit_jingmai(src_unit, "九黎城", "震怒")) {
					gl = gl * 2;
				}
				if (G.RandomUtils.chance(gl)) {
					G.FightStatusUtils.add_unit_status(fight_data, src_unit, src_unit, "怒哮");
				}
			}
		}
	}

	damage = Math.floor(damage);

	// 最终伤害
	let final_damage = G.FightPhysicalAttack.get_final_ad_damage(fight_data, src_unit, target_unit, damage, default_damage["必杀几率"], default_damage["暴击倍率"]);

	//随机保护
	let bh = false;
	let bh_unit;
	if (target_unit["类型"] === "角色" && target_unit["气血"] < target_unit["最大气血"] * 0.5 && (final_damage["伤害"] * 0.3) < target_unit["气血"]
		&& final_damage["伤害"] > (target_unit["最大气血"] * 0.1) && G.RandomUtils.chance(70) && src_unit["队伍"] !== target_unit["队伍"]) {
		let sjbh = [];
		for (let index = 0; index < fight_data["队伍数据"].length; index++) {
			let team = fight_data["队伍数据"][index];
			if (team[0].队伍 === target_unit["队伍"]) {
				team.forEach(unit => {
					if (bh_unit === undefined && G.FightUnitUtils.get_unit_process_status(fight_data, unit)
						&& (target_unit["法术状态"] || target_unit["法术状态"]["惊魂掌"] === undefined)
						&& unit["类型"] === "角色" && unit["编号"] !== target_unit["编号"]) {
						sjbh.push(unit);
					}
				})
			}
		}
		if (sjbh.length > 0) {
			bh_unit = G.RandomUtils.random_get_array(sjbh);
			bh = true;
		}
	} else {
		for (let index = 0; index < fight_data["队伍数据"].length; index++) {
			let team = fight_data["队伍数据"][index];
			if (team[0].队伍 === target_unit["队伍"]) {
				for (let j = 0; j < team.length; j++) {
					let unit = team[j];
					if (G.FightUnitUtils.get_unit_process_status(fight_data, unit) && target_unit["法术状态"]["惊魂掌"] === undefined
						&& unit["指令"] && unit["指令"]["类型"] === "保护" && unit["指令"]["目标"] !== target_unit["编号"]) {
						bh_unit = unit;
						bh = true;
						unit["指令"]["类型"] = "";
						break;
					}
				}
			}
		}
	}

	// 被攻击目标使用防御指令的处理
	let fy = false;
	if (target_unit["指令"] && target_unit["指令"]["类型"] === "防御"
		&& G.FightUnitUtils.get_unit_process_status(fight_data, target_unit) && G.FightUnitUtils.get_unit_defence_status(target_unit)) {
		if (skill_name === "壁垒击破") {
			final_damage["伤害"] = final_damage["伤害"] * 1.2;
		} else {
			final_damage["伤害"] = final_damage["伤害"] * 0.5;
		}
		final_damage["动作"] = "防御";
		fy = true;
		if (target_unit["点石成金"]) {
			final_damage["伤害"] = final_damage["伤害"] * target_unit["点石成金"];
		}
		if (target_unit["法术状态"] && target_unit["法术状态"]["愈勇"]) {
			G.FightStatusUtils.canel_unit_status(fight_data, "愈勇", target_unit);
		}
	}

	// let csjc = 0;
	// if (G.FightUnitUtils.check_fight_unit_jingmai(src_unit, "九黎城", "狂暴")) {
	// 	for (let index = 0; index < final_damage["特效"].length; index++) {
	// 		if (final_damage["特效"][index] === "暴击") {
	// 			csjc += 1;
	// 		}

	// 	}
	// }
	// 战斗数据:九黎城连击数处理(编号, 1 + csjc)


	let damage_result = G.FightComputingUtils.get_damage_result(fight_data, src_unit, target_unit, final_damage["伤害"], final_damage["暴击"], skill_name, bh, fy, 1);

	// 共生计算
	if (target_unit["共生"]) {
		G.FightPhysicalAttack.computing_physical_damage_gs(fight_data, src_unit, target_unit, damage_result["伤害"] + 1, final_damage["动作"], damage_result["特效"], commone_data["返回"]);
		return;
	}

	// 溅射计算
	if (skill_data["溅射计算"]) {
		skill_data["溅射计算"](fight_data, src_unit, target_unit, damage);
		// 溅射不触发保护
		bh = false;
	}

	// 指定技能不触发保护
	if (skill_data["不可保护"]) {
		bh = false;
	}

	// 保护计算
	if (bh) {
		let bh_damage_ratio = 0.7;
		let damage_ratio = 0.3;
		if (src_unit["势如破竹"]) {
			bh_damage_ratio = 0.4;
			damage_ratio = 0.6;
		}
		if (bh_unit["内丹属性"]["阴阳护"]) {
			bh_damage_ratio -= bh_unit["阴阳护"];
		}
		// 进行保护的单位承受的伤害
		let bh_damage = Math.floor(damage_result["伤害"] * bh_damage_ratio);
		if (bh_damage < 1) { bh_damage = 1; }
		console.debug(`保护 单位掉血计算`)
		let bh_die = G.FightComputingUtils.computing_remove_hp(fight_data, src_unit, bh_unit, bh_damage);

		// 保护增伤
		if (G.FightUnitUtils.check_fight_unit_jingmai(src_unit, "大唐官府", "破空")) {
			damage_result["伤害"] = Math.floor(damage_result["伤害"] * 1.1);
		}
		// 技能保护增伤
		if (skill_data["保护增伤"]) {
			skill_data["保护增伤"](fight_data, src_unit, target_unit, damage_result["伤害"])
		}
		// 被保护单位承受的伤害
		damage_result["伤害"] = Math.floor(damage_result["伤害"] * damage_ratio);

		fight_data["战斗流程"][current_process_data_index]["保护数据"] = { "编号": bh_unit["编号"], "伤害": bh_damage, "死亡": bh_die };
		G.FightUtils.add_waiting_play_time(fight_data, 1, "物理技能保护");
	}

	// 概率增伤回血
	if (skill_data["概率增伤回血"]) {
		let res = skill_data["概率增伤回血"](fight_data, src_unit, target_unit, damage_result["伤害"]);
		if (res === false) {
			return;
		}
	}

	// 统一处理一次伤害数值 保持整数
	damage_result["伤害"] = Math.floor(damage_result["伤害"]);
	if (damage_result["伤害"] < 1 || target_unit["物理免疫"]) {
		damage_result["伤害"] = 1;
	}

	// 根据伤害结果决定是增加气血还是扣除气血
	if (damage_result["类型"] === 2) {
		//恢复气血
		G.FightComputingUtils.add_target_hp_and_play(fight_data, target_unit, damage_result["伤害"]);
	} else {
		let die = G.FightComputingUtils.computing_remove_hp(fight_data, src_unit, target_unit, damage_result["伤害"], skill_name);
		fight_data["战斗流程"][current_process_data_index]["被攻击"][0]["死亡"] = die;
		// 物理技能掉血计算
		if (skill_data["掉血计算"]) {
			skill_data["掉血计算"](fight_data, src_unit, target_unit, damage_result["伤害"]);
		}
	}

	fight_data["战斗流程"][current_process_data_index]["被攻击"][0]["动作"] = final_damage["动作"];
	fight_data["战斗流程"][current_process_data_index]["被攻击"][0]["特效"] = damage_result["特效"];

	// 除特定技能都增加特效
	if (!skill_data["不加特效"] && !fight_data["战斗流程"][current_process_data_index]["被攻击"][0]["特效"].includes(skill_name)) {
		fight_data["战斗流程"][current_process_data_index]["被攻击"][0]["特效"].push(skill_name);
	}

	//吸血
	let xx = src_unit["吸血"];
	if (xx === undefined && src_unit["法术状态"]["移魂化骨"]) {
		xx = src_unit["法术状态"]["移魂化骨"]["吸血"];
	}
	if (xx && !target_unit["特殊状态"]["鬼魂术"]) {
		let xx_damage = Math.floor(damage_result["伤害"] * xx);
		if (xx_damage < 1) {
			xx_damage = 1;
		}
		//增加气血
		G.FightComputingUtils.add_target_hp_and_play(fight_data, src_unit, xx_damage);
		fight_data["战斗流程"][current_process_data_index]["吸血伤害"] = xx_damage;
		if (xx < 0.3 && src_unit["法术状态"]["毒"] === undefined && G.FightUnitUtils.get_error_xx_status(target_unit)) {
			G.FightStatusUtils.add_unit_status(fight_data, src_unit, target_unit, "毒", 11);
		}
		let ycsh = damage_result["伤害"] - xx;
		if (ycsh >= 1 && src_unit["超级吸血"]) {
			// 添加护盾
			G.FightUnitUtils.add_hu_dun_for_lt_hp(fight_data, src_unit, ycsh);
		}
		else if (G.FightUnitUtils.check_fight_unit_jingmai(src_unit, "狮驼岭", "化血") && G.RandomUtils.chance(30)) {
			let xx_damage = Math.floor(damage_result["伤害"] * 0.16)
			if (xx_damage < 1) {
				xx_damage = 1;
			}
			//增加气血
			G.FightComputingUtils.add_target_hp_and_play(fight_data, src_unit, xx_damage);
			fight_data["战斗流程"][current_process_data_index]["吸血伤害"] = xx_damage;
			if (src_unit["法术状态"]["毒"] === undefined && G.FightUnitUtils.get_error_xx_status(target_unit)) {
				G.FightStatusUtils.add_unit_status(fight_data, src_unit, target_unit, "毒", 11);
			}
		} else if (src_unit["法术状态"]["狂怒"] && src_unit["法术状态"]["狂怒"]["攫取"] && G.RandomUtils.chance(50)) {
			let xx_damage = Math.floor(damage_result["伤害"] * 0.16)
			if (xx_damage < 1) {
				xx_damage = 1;
			}
			//增加气血
			G.FightComputingUtils.add_target_hp_and_play(fight_data, src_unit, xx_damage);
			fight_data["战斗流程"][current_process_data_index]["吸血伤害"] = xx_damage;

			if (src_unit["法术状态"]["毒"] === undefined && G.FightUnitUtils.get_error_xx_status(target_unit)) {
				G.FightStatusUtils.add_unit_status(fight_data, src_unit, target_unit, "毒", 11);
			}
		}
	}

	let fz = target_unit["特殊状态"]["反震"];


	//触发反震 有保护的情况下不会触发反震
	if (!bh && damage_result["伤害"] >= 4 && !src_unit["特殊状态"]["偷袭"] && fz && G.RandomUtils.chance(target_unit["特殊状态"]["反震"]["概率"])) {
		let fz_damage = Math.floor(damage_result["伤害"] * target_unit["特殊状态"]["反震"]["伤害"]);
		if (target_unit["内丹属性"]["坚甲"]) {
			fz_damage += target_unit["内丹属性"]["坚甲"];
		}
		if (G.FightUnitUtils.check_fight_unit_jingmai(src_unit, "狮驼岭", "狂袭")) {
			G.FightStatusUtils.add_unit_status(fight_data, src_unit, src_unit, "狂袭", Math.floor(fz_damage * 0.04));
		}
		fight_data["战斗流程"][current_process_data_index]["反震伤害"] = fz_damage;
		let die = G.FightComputingUtils.computing_remove_hp(fight_data, target_unit, src_unit, fz_damage);
		fight_data["战斗流程"][current_process_data_index]["被攻击"][0]["死亡"] = die;
		fight_data["战斗流程"][current_process_data_index]["反震死亡"] = die;
		fight_data["战斗流程"][current_process_data_index]["被攻击"][0]["特效"].push("反震");
		if (src_unit["法术状态"]["狂袭"] && src_unit["气血"] <= 0) {
			src_unit["气血"] = 1;
			fight_data["战斗流程"][current_process_data_index]["反震死亡"] = false;
			src_unit["法术状态"]["狂袭"]["死亡"] = true;
		}
		G.FightUtils.add_waiting_play_time(fight_data, 1, "物理技能反震");
	}

	// 修罗咒被攻击反震计算
	if (target_unit["法术状态"]["修罗咒"]) {
		G.SkillData.default["修罗咒"]["反震计算"](fight_data, src_unit, target_unit, damage);
	}

	console.debug(`物攻技能流程计算 => 伤害: ${damage_result["伤害"]}`);
	fight_data["战斗流程"][current_process_data_index]["被攻击"][0]["伤害"] = damage_result["伤害"];
	fight_data["战斗流程"][current_process_data_index]["被攻击"][0]["伤害类型"] = damage_result["类型"];
	fight_data["战斗流程"][current_process_data_index]["返回"] = commone_data["返回"];
	if (commone_data["返回"]) {
		G.FightUtils.add_waiting_play_time(fight_data, 1, "物理技能返回");
	}
}